#include "GroupNode.h"
#include "NodeVisitor.h"
namespace sl
{
	
	GroupNode::GroupNode(void)
	{
	}

	GroupNode::GroupNode( const GroupNode & groupNode )
	{
		for ( ChildList::const_iterator childit = groupNode.m_vChildList.begin();
			childit !=  groupNode.m_vChildList.end(); ++childit )
		{
			Node * child = childit->get();
			if ( child ) AddChild( child );
		}
	}

	GroupNode::~GroupNode(void)
	{
		for ( ChildList::iterator childit = m_vChildList.begin();
			childit != m_vChildList.end(); ++childit )
		{
			(*childit)->RemoveFromParent(this);
		}

		m_vChildList.clear();
	}

	bool GroupNode::AddChild( Node * pChild )
	{
		return GroupNode::InsertChild( m_vChildList.size(), pChild );
	}

	bool GroupNode::RemoveChild( Node * pChild )
	{
		return RemoveChild( findchildindex( pChild ) );
	}

	bool GroupNode::InsertChild( u32 nIndex, Node * pChild )
	{
		if ( pChild == NULL )	
			return false;
		
		if ( nIndex > m_vChildList.size() )
		{
			m_vChildList.push_back( pChild );
		}
		else
		{
			m_vChildList.insert( m_vChildList.begin() + nIndex, pChild );
		}

		pChild->SetParent( this );

		return true;
	}

	bool GroupNode::RemoveChild( u32 nIndex )
	{
		if ( nIndex > m_vChildList.size() )
			return false;

		sl::Node * child = m_vChildList[nIndex].get();
		child->RemoveFromParent( this );
		
		m_vChildList.erase( m_vChildList.begin() + nIndex );

		return true;
	
	}

	bool GroupNode::RemoveChild( u32 nIndex, u32 nRemoveNum )
	{
		if ( nIndex < m_vChildList.size() && nRemoveNum > 0 )
		{
			u32 nEndRemovePos = nIndex + nRemoveNum;
			for ( u32 i = nIndex; i < nEndRemovePos; i++ )
			{
				sl::Node * child = m_vChildList[i].get();
				child->RemoveFromParent( this );
			}
			m_vChildList.erase( m_vChildList.begin() + nIndex, m_vChildList.begin() + nEndRemovePos );
		}
		else 
			return false;
		return true;
	}

	void GroupNode::Accept( sl::NodeVisitor * pNodeVisitor )
	{
		pNodeVisitor->Apply( this );
	}

	void GroupNode::Ascend( sl::NodeVisitor * pNodeVisitor )
	{

	}

	void GroupNode::Traverse( sl::NodeVisitor * pNodeVisitor )
	{

	}

	// protected or private
	u32 GroupNode::findchildindex( sl::Node * child )
	{
		for ( u32 iFindChildIndex = 0; iFindChildIndex < m_vChildList.size(); ++iFindChildIndex )
		{
			if ( m_vChildList[iFindChildIndex].get() == child )
				return iFindChildIndex; // return the find index
		}
		
		return m_vChildList.size(); // not find the child return the last index
	}

}
